#include "optraapplication.h"

#include <Core/logger/logger.h>
#include <Core/task.h>
#include <QUuid>
#include <tasks.h>
#include <zones.h>
#include <configmanager.h>
#include <server/tcpserver.h>


namespace Optra {

class OptraApplicationPrivate
{
public:
    OptraApplicationPrivate() {}
    ~OptraApplicationPrivate() {}
    TasksController* tasks;
    Zones* zones;
    Optra::Server::TcpServer* server;
};

class TaskTest : public Opl::Core::Task
{
private:
    void run(){
        while(!quitNow())
        {
            qDebug() << "Tick";
            Opl::Core::Task::sleep(5);

        }
    }
};

OptraApplication::OptraApplication(Opl::Core::EntityObject *parent) :
    Opl::Core::EntityObject(parent), O_PRIVATE_CREATE(OptraApplication)
{
    O_D(OptraApplication);
    //d->
}

OptraApplication::~OptraApplication()
{
    O_D(OptraApplication);

    O_PRIVATE_DELETE;
}

bool OptraApplication::Initialize()
{
    Opl::Core::Logger::Initialize();//("optra.log", Opl::Core::LoggerItem::TRACE);
    LI.Info() << "Optra Initialize";


    O_D(OptraApplication);



    ConfigManager::instance()->registerConfig(unique(), "config/Optra.cfg", false);
    d->tasks = new TasksController(this);

    d->zones = new Zones(this);
    //TaskTest* tt = new TaskTest;
    //d->tasks->start(tt);

    d->zones->loadZones();

    d->server = new Optra::Server::TcpServer(this);
    d->server->start();

    return true;
}

void OptraApplication::Finalize()
{
    O_D(OptraApplication);
    d->server->close();
}

TasksController *OptraApplication::tasks() const
{
    O_C(OptraApplication);
    return d->tasks;
}

OptraApplication *OptraApplication::Instance()
{
    static OptraApplication app;
    return &app;
}

QVariant OptraApplication::globalConfig(const QString &section, const QString &key, const QVariant &def)
{
    return conf(*this, section, key, def);
}

}

extern "C" EXPORTED int optra_entry(int argc, char **argv)
{
    //TODO: setup application properties
    //QApplication app(argc, argv);
    //app.setOrganizationName("Optra System");
    //app.setApplicationName("Optra");
    QCoreApplication::setOrganizationDomain("optra.org");

    Opl::Core::Logger::Initialize();
    if (!Optra::OptraApplication::Instance()->Initialize())
    {
        LI.Fatal() << "initialize failed";
        return -1;
    }
}

int main (int argc, char**argv)
{
    return optra_entry(argc, argv);
}
